package com.distribution.system.manager.channel.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.distribution.common.core.redis.RedisCache;
import com.distribution.common.exception.ServiceException;
import com.distribution.common.utils.StringUtils;
import com.distribution.common.utils.spring.SpringUtils;
import com.distribution.system.domain.bo.*;
import com.distribution.system.domain.dto.ChoosePhoneDTO;
import com.distribution.system.domain.dto.SendCodeDTO;
import com.distribution.system.domain.entity.*;
import com.distribution.system.domain.req.ReqResult;
import com.distribution.system.manager.channel.AbstractChannel;
import com.distribution.system.manager.channel.channelInfo.enums.OneSixEightChannelEnum;
import com.distribution.system.manager.channel.channelInfo.enums.QiuKuiChannelEnum;
import com.distribution.system.service.AddressChannelService;
import com.distribution.system.service.CmccDaOrderService;
import com.distribution.system.service.CmccDaProductService;
import com.distribution.system.utils.http.HttpRequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: GodLu
 * @create: 2024-04-05 14:49
 * @description: 秋葵接口
 */
@Slf4j
public class QiuKuiChannel extends AbstractChannel {
    private static final Logger qkOrderSearchLog = LoggerFactory.getLogger("qkOrderSearchLog");
    private static final String CHECK_CODE_PREFIX = "CHECK_CODE_PREFIX-";

    public QiuKuiChannel(CmccDaUpChannelInfoBO cmccDaUpChannelInfoBO) {
        super(cmccDaUpChannelInfoBO);
    }

    @Override
    public AddressInfoBo getChannelAddressInfo(AddressNameBo addressNameBo, AddressChannelService addressChannelService) {
        return null;
    }

    @Override
    public String configPlaceOrderRequestParams(CmccDaOrder cmccDaOrder, CmccDaProduct cmccDaProduct, AddressInfoBo addressInfoBo) {
        log.info("配置秋葵下单接口参数...");
        AddressChannel addressInfo = addressInfoBo.getAddressInfo();
        AddressChannel attributeInfo = addressInfoBo.getAttributeInfo();
        // 生成订单号
        orderId = "QK" + DateUtil.format(DateUtil.date(), "yyyyMMdd") + IdUtil.getSnowflake(1, 1).nextIdStr().substring(8,18);
        // 配置请求参数
        HashMap<String, Object> map = new HashMap<>(1 << 4);
        if ("1".equals(cmccDaProduct.getBroadbandFlag())){// 宽带
            //map.put("custom", cmccDaOrder.getOrderId());
            map.put("channel", cmccDaProduct.getProductParam());
            map.put("province", cmccDaOrder.getAddressProvince());
            map.put("city", cmccDaOrder.getAddressCity());
            map.put("district", cmccDaOrder.getAddressArea());
            map.put("address", cmccDaOrder.getAddressStreet());
            map.put("cardName", cmccDaOrder.getCustomerName());
            map.put("cardNum", cmccDaOrder.getCustomerCertNo());
            map.put("phone", cmccDaOrder.getCustomerPhone());
            map.put("source", "qk");//上游说默认qk就好
            //map.put("oldChannel", "");//未知（不是必需参数）
            //map.put("cps1", "");//标识（不是必需参数）
            //map.put("goodNumber", "");//是否靓号 1是，仅支持联通（不是必需参数）
            if (!"1".equals(cmccDaProduct.getBroadbandFlag()) && "1".equals(cmccDaProduct.getCodeFlag())) {
                map.put("captcha", cmccDaOrder.getCode());
            }
        }else {// 非宽带
            map.put("channel", cmccDaProduct.getProductParam());
            HashMap<String, Object> configMap = new HashMap<>(1 << 4);
            configMap.put("cps1", "");// 标识
            configMap.put("token", getToken(cmccDaProduct.getProductParam()));// 登录令牌
            configMap.put("click_id", "");// 区别广告位,后台可以查看
            configMap.put("jlqk_link", "");// 当前投放链接
            configMap.put("enId", "");// 选号标识，选号接口返回，非选号或为空则不传
            map.put("config", configMap);// 请求内容
            HashMap<String, Object> postInfoMap = new HashMap<>(1 << 4);
            postInfoMap.put("webProvince", addressInfo.getProvinceCode());// 发货省份 地址接口的code
            postInfoMap.put("webCity", addressInfo.getCityCode());// 发货市 地址接口的code
            postInfoMap.put("webCounty", addressInfo.getDistrictCode());// 发货区 地址接口的code
            postInfoMap.put("f_province_name", addressInfo.getProvinceName());// 发货省 地址名称
            postInfoMap.put("f_city_name", addressInfo.getCityName());// 发货市 地址名称
            postInfoMap.put("f_district_name", addressInfo.getDistrictName());// 发货区 地址名称
            postInfoMap.put("address", cmccDaOrder.getAddressStreet());// 发货详细地址名称 (不少于6位字符)
            map.put("postInfo", postInfoMap);// 发货内容
            HashMap<String, Object> numInfoMap = new HashMap<>(1 << 4);
            numInfoMap.put("public", true);// 号码属性
            numInfoMap.put("number", cmccDaOrder.getChoosePhone());// 订购号码
            //redis缓存获取
            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
            numInfoMap.put("numberCheckCode", redisCache.getCacheObject(CHECK_CODE_PREFIX + cmccDaOrder.getChoosePhone()));// 号码令牌 (选号必填) 选号numberCheckCode
            numInfoMap.put("essProvince", attributeInfo.getEssProvinceCode());// 号码归属省
            numInfoMap.put("essCity", attributeInfo.getEssCityCode());// 号码归属市
            numInfoMap.put("province_name", attributeInfo.getProvinceName());// 号码归属省名称
            numInfoMap.put("city_name", attributeInfo.getCityName());// 号码归属市名称
            map.put("numInfo", numInfoMap);// 号码内容
            HashMap<String, Object> certInfoMap = new HashMap<>(1 << 4);
            certInfoMap.put("certName", cmccDaOrder.getCustomerName());// 身份姓名
            certInfoMap.put("certId", cmccDaOrder.getCustomerCertNo());// 身份证件号
            certInfoMap.put("contractPhone", cmccDaOrder.getCustomerPhone());// 联系号码
            map.put("certInfo", certInfoMap);// 身份内容
            HashMap<String, Object> captchaInfoMap = new HashMap<>(1 << 4);
            if ("1".equals(cmccDaProduct.getCodeFlag())){
                captchaInfoMap.put("captcha", cmccDaOrder.getCode());// 验证码
            }
            map.put("captchaInfo", captchaInfoMap);// 验证内容
        }
        return new JSONObject(map).toString();
    }
    @Override
    public String sendPlaceOrderRequest(String requestJsonStr) {
        JSONObject jsonObject = JSON.parseObject(requestJsonStr);
        // 号卡
        if (!Objects.isNull(jsonObject) && !Objects.isNull(jsonObject.getJSONObject("config"))){
            return HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.PLACE_ORDER.getName()), requestJsonStr);
        }else {// 宽带
            return HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.KD_PLACE_ORDER.getName()), requestJsonStr);
        }
    }
    @Override
    public ReqResult parsePlaceOrderResponseStr(JSONObject responseJsonObject) {
        //响应
        JSONObject resultJson = responseJsonObject.getJSONObject("result");
        if (resultJson != null) {// resultJson不为空时为宽带解析
            if (!"1".equals(resultJson.getString("code"))) {
                return ReqResult.error(resultJson.getString("message"));
            } else {
                JSONObject dataJson = resultJson.getJSONObject("resultCreateOrder").getJSONObject("data");
                UnOrderResultBo unOrderResultBo = new UnOrderResultBo();
                unOrderResultBo.setOrderId(orderId);
                unOrderResultBo.setChannelOrderNo(dataJson.getJSONArray("no").get(0).toString());// 内部订单号
                return ReqResult.success(dataJson.getString("message"), unOrderResultBo);
            }
        }else {// resultJson为空时为号卡解析
            String msg = responseJsonObject.getString("msg");
            if (!"2000".equals(responseJsonObject.getString("code"))){
                return ReqResult.error(msg);
            }else {
                JSONObject dataJson = responseJsonObject.getJSONObject("data");
                UnOrderResultBo unOrderResultBo = new UnOrderResultBo();
                unOrderResultBo.setOrderId(orderId);
                unOrderResultBo.setChannelOrderNo(dataJson.getJSONArray("no").get(0).toString());// 内部订单号
                return ReqResult.success(msg, unOrderResultBo);
            }
        }
    }



    @Override
    public String configChoosePhoneRequestParams(ChoosePhoneDTO choosePhoneDTO, CmccDaProduct cmccDaProduct, AddressInfoBo addressInfoBo) {
        log.info("请求秋葵选择号码接口...");
        HashMap<String, Object> map = new HashMap<>(1 << 2);
        map.put("channel", cmccDaProduct.getProductParam());
        map.put("token", getToken(cmccDaProduct.getProductParam()));
        map.put("essProvince", addressInfoBo.getAttributeInfo().getEssProvinceCode());
        map.put("essCity", addressInfoBo.getAttributeInfo().getEssCityCode());
        map.put("province_name", addressInfoBo.getAttributeInfo().getProvinceName());
        map.put("city_name", addressInfoBo.getAttributeInfo().getCityName());
        map.put("webProvince", addressInfoBo.getAddressInfo().getProvinceCode());
        map.put("webCity", addressInfoBo.getAddressInfo().getCityCode());
        //map.put("certId", choosePhoneDTO.getCertNum());// 身份证号码（指定产品）
        map.put("searchValue", StringUtils.isBlank(choosePhoneDTO.getKeywords()) ? "" : choosePhoneDTO.getKeywords());// 搜索字段
        return new JSONObject(map).toString();
    }
    private String getToken(String channel){
        log.info("获取秋葵配置信息...");
        HashMap<String, Object> map = new HashMap<>(1 << 2);
        map.put("channel", channel);
        String requestJsonStr = new JSONObject(map).toString();
        // 请求
        String responseJsonStr = HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.GET_CONFIG.getName()), requestJsonStr);
        // 响应
        JSONObject resultJson = JSONObject.parseObject(responseJsonStr);
        // 解析
        if ("2000".equals(resultJson.getString("code"))){
            return resultJson.getJSONObject("data").getString("token");
        }
        return resultJson.getString("msg");
    }
    @Override
    public String sendChoosePhoneRequest(String requestJsonStr) {
        return HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.CHOOSE_PHONE.getName()), requestJsonStr);
    }
    @Override
    public ReqResult parseChoosePhoneResponseStr(JSONObject responseJsonObject) {
        String msg = responseJsonObject.getString("msg");
        if (!"2000".equals(responseJsonObject.getString("code"))) {
            return ReqResult.error(msg);
        } else {
            JSONObject data = responseJsonObject.getJSONObject("data");
            JSONArray phoneNumberArray = data.getJSONArray("numberList");
            List<String> numArray = new ArrayList<>();
            //这里不知道为什么自动注入得到的redis对象为null，所以反射调用
            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
            for (int i = 0; i < phoneNumberArray.size(); i++) {
                JSONObject jsonObject = phoneNumberArray.getJSONObject(i);
                if (!Objects.isNull(jsonObject)){
                    String number = String.valueOf(jsonObject.getLong("number"));
                    numArray.add(number);
                    // redis存储
                    redisCache.setCacheObject(CHECK_CODE_PREFIX + number, jsonObject.getString("numberCheckCode"));
                }
            }
            ChoosePhoneResultBO choosePhoneResultBO = new ChoosePhoneResultBO();
            choosePhoneResultBO.setNumArray(numArray);
            return ReqResult.success(choosePhoneResultBO);
        }
    }



    @Override
    public ReqResult sendCardSmsCode(CmccDaProduct cmccDaProduct, SendCodeDTO sendCodeDTO) {
        HashMap<String, Object> map = new HashMap<>(1 << 2);
        map.put("channel",cmccDaProduct.getProductParam());
        map.put("smsCode",1);//默认1
        map.put("phone",sendCodeDTO.getCustomerPhone());
        String requestJson = new JSONObject(map).toString();
        JSONObject jsonObject = JSONObject.parseObject(HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.SEND_SMS.getName()), requestJson));
        if (!"2000".equals(jsonObject.getString("code"))) {
            return ReqResult.error(jsonObject.getString("msg"));
        } else {
            return ReqResult.success(jsonObject.getString("msg"));
        }
    }

    @Override
    public RefreshOrderBO getRefreshOrderBO(CmccDaOrder cmccDaOrder) {
        // 秋葵是根据三方单号更新的
        List<CmccDaOrder> orderList = new ArrayList<>();
        orderList.add(cmccDaOrder);
        Map<CmccDaOrder,RefreshOrderBO> refreshOrderBOMap = getRefreshOrderBOList(orderList);
        return refreshOrderBOMap.isEmpty() ? null : refreshOrderBOMap.get(cmccDaOrder);
    }

    @Override
    public Map<CmccDaOrder,RefreshOrderBO> getRefreshOrderBOMap(List<CmccDaOrder> orderList) {
        return getRefreshOrderBOList(orderList);
    }
    private Map<CmccDaOrder,RefreshOrderBO> getRefreshOrderBOList(List<CmccDaOrder> orderList){
        List<CmccDaOrder> subList = orderList.subList(0, Math.min(100, orderList.size()));
        String channelOrderNos = subList.stream().map(CmccDaOrder::getChannelOrderNo).collect(Collectors.joining(","));
        HashMap<String, Object> map = new HashMap<>(1 << 2);
        map.put("channel", orderList.get(0).getProductParam());
        map.put("orderSn", channelOrderNos);
        String requestJson = new JSONObject(map).toString();
        qkOrderSearchLog.info("【秋葵】批量查单请求 => {}",requestJson);
        JSONObject responseJson = JSONObject.parseObject(HttpRequestUtils.sendPost(interfaceUrlsMap.get(QiuKuiChannelEnum.SELECT_ORDER.getName()), requestJson));
        qkOrderSearchLog.info("【秋葵】批量查单响应 => {}",responseJson.toString());
        Map<CmccDaOrder,RefreshOrderBO> refreshOrderBOMap = new HashMap<>();
        if (!"2000".equals(responseJson.getString("code"))){// 失败
            throw new ServiceException(responseJson.getString("msg"));
        }
        JSONArray jsonArray = responseJson.getJSONArray("data");
        if (!jsonArray.isEmpty()) {
            for (Object object : jsonArray) {
                JSONObject json = (JSONObject) object;
                RefreshOrderBO refreshOrderBO = new RefreshOrderBO();
                String status = "2";
                String productStatus = "-1";
                // 号卡状态（小于0提单成功 0 失败 1下单成功 2 已发货 3 已撤单 4 已签收 5 已激活 6 已首充）宽带状态（0 失败 1下单成功 3 已撤单 6 已竣工）
                Integer state = json.getInteger("isSuccess");
                if (state == 6) {
                    status = "3";
                    productStatus = "6";
                }
                if (state == 0) {
                    status = "-1";
                    productStatus = "-2";
                }
                if (state == 2){
                    productStatus = "11";
                }
                if (state == 5){
                    productStatus = "1";
                }
                refreshOrderBO.setStatus(status);
                refreshOrderBO.setProductStatus(productStatus);
                refreshOrderBO.setChannelOrderNo(json.getString("orderSn"));// 渠道方订单号
                refreshOrderBO.setStatusMsg(json.getString("description"));// 状态描述
                // 这里首冲金额单位是元，需要转换为分
                String rechargeAmount = json.getString("rechargeAmount");// 充值金额
                String s = StringUtils.isEmpty(rechargeAmount) ? "0" : (new BigDecimal(rechargeAmount).multiply(new BigDecimal(100))).toString();
                refreshOrderBO.setScMoney(s);
                // 首冲金额不为空且>0则已首充
                refreshOrderBO.setProductStatus(Integer.parseInt(s) > 0 ? "6" : "-1");
                refreshOrderBO.setPhone(json.getString("selectPhone"));// 订购号码
                refreshOrderBO.setCreateTime(json.getString("orderTime"));// 订购时间
                refreshOrderBO.setLimitTime(json.getString("activeTime"));// 激活时间
                String logisticsInfo = StringUtils.isNotBlank(json.getString("logisticsName")) && StringUtils.isNotBlank(json.getString("logisticsNum")) ?
                        json.getString("logisticsName") + "-" + json.getString("logisticsNum") : "无";
                refreshOrderBO.setLogisticsInfo(logisticsInfo);// 物流名称-物流单号
                CmccDaOrder cmccDaOrder = orderList.stream().filter(a -> StringUtils.equals(a.getChannelOrderNo(), refreshOrderBO.getChannelOrderNo())).collect(Collectors.toList()).get(0);
                refreshOrderBOMap.put(cmccDaOrder, refreshOrderBO);
            }
        }
        return refreshOrderBOMap;
    }

    @Override
    public void refreshChannelCommission(CmccDaUpChannelInfo cmccDaUpChannelInfo) {
    }
}
